<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<!--
js 类型转换
number() 转换数值
string() 转换字符串
boolean() 转换布尔值

js 五种可包含值的数据类型
字符串 string
数值  number
布尔  boolean
对象 object
函数  function

有三种对象类型
对象 object
日期  Date
数组  Array

同时有两种不能包含值的数据类型
null
undefined

使用typeof 运算符来确定 js 变量的数据类型
typeof "Bill"                 // 返回 "string"
typeof 3.14                   // 返回 "number"
typeof NaN                    // 返回 "number"
typeof false                  // 返回 "boolean"
typeof [1,2,3,4]              // 返回 "object"
typeof {name:'Bill', age:62}  // 返回 "object"
typeof new Date()             // 返回 "object"
typeof function () {}         // 返回 "function"
typeof myCar                  // 返回 "undefined" *
typeof null                   // 返回 "object"

请注意：

NaN 的数据类型是数值
数组的数据类型是对象
日期的数据类型是对象
null 的数据类型是对象
未定义变量的数据类型是 undefined
尚未赋值的变量的数据类型也是 undefined
您无法使用 typeof 去判断 JavaScript 对象是否是数组（或日期）。


typeof 的数据类型
typeof 运算符不是变量.它属于运算符.运算符没有数据类型,但是 typeof 始终会返回字符串

constructor 属性返回所有 js 变量的构造器函数
通过检查 constructor 属性,来确定某个对象是否为数组 包含单词 Array
检查对象是否是数组函数
function isArray(myArray) {
  return myArray.constructor === Array;
}

js 类型转换 变量能够被转换为新变量以及另一种数据类型
通过 使用js 函数
通过 js 本身自动转换

把数值 转换为字符串  全局方法 String() 能够把数字转换为字符串
它可用于 任意类型的数字 文字 变量 或表达式

位运算 AND
当对一对 数位执行位运算AND时 如果数位均为1 则返回1

位运算 OR
当对一对 数位执行位运算OR时 如果其中一位是1 则返回1

位运算符 XOR
当对一对 数位执行位运算XOR时 如果数位是不同的则返回1

js 位运算符 AND &
如果位数是1 则位运算AND返回1

js 位运算符 OR |
如果其中一位是1 则位运算OR返回1

js 位运算符 XOR ^
如果数位是不同的 则XOR返回1

js 位运算符 NOT ~

js 零填充 位运算左移 <<
这是零填充的左移 一个或多个零数位从右被推入  最左侧的数位被移除

js 零填充 位运算右移 >>
这是零填充的右移 一个或多个零数位从左被推入  最右侧的数位被移除

js 零填充 右移 >>>
这是零填充的右移 一个或多个零数位从左被推入  最右侧的数位被移出

js 位运算符 左移 <<
这是无符号的左移 一个或多个零数位从左被推入  最左侧的数位被移出

js 正则表达式
正则表达式 是构成搜索模式的字符序列 该搜索模式可用于文本搜索和文本替换操作
正则表达式是构成搜索模式 的字符序列 当您搜索文本中 的数据时,可以使用搜索模式来描述搜索的内容
w3school/i 是一个正则表达式
正则表达式 常用于两个 字符串方法 search() 和 replace()
search() 方法使用表达式来搜索匹配 然后返回匹配的位置
replace() 方法返回模式被替换处修改后的字符串

正则表达式 修改符
修饰符可用于大小写不敏感的更全局的搜索
i 执行对大小写不敏感的搜索
g 执行全局匹配 (查找所有匹配而非在找到第一个匹配后停止)
m 执行多行匹配

括号 用于查找一定范围的 字符串
[abc] 查找方括号之间的任何字符
[0-9] 查找任何0-9的数字
(x|y) 查找由 | 分隔的任何选项

元字符 拥有特殊含义的字符
\d 查找数字
\s 查找空白字符
\b 匹配单词边界
\uxxx 查询以十六进制数 xxx 规定的unicode 字符


test() 是一个正则表达式方法 通过模式来搜索字符串 然后返回结果返回 true 或 false
使用 exec() 方法是一个正则表达式方法  它通过指定的模式 pattern 搜索字符串,并返回已找到的文本
如果 未找到匹配,则返回 null 下面的例子 搜索字符串的字符 "e"

运算符优先级 描述了算术表达式中运算的执行顺序
乘法 和除法 的优先级 高于加法 和减法
使用 圆括号时 先计算圆括号内的运算
优先级相同的运算 如(* 和 /)从左到右计算
let x = 100/50 * 3;

js 错误 throw 和 try to catch
try 语句能够测试代码块中的错误
catch 语句允许处理错误
throw 语句允许创建自定义错误
finally 语句允许执行代码无论 try 或 catch 语句的运行结果如何.

错误 总会抛出异常 当执行js代码 会发生各种错误
js 将adddlert 捕获为一个错误 然后执行代码来处理错误

js try和catch语句
try 语句允许定义一个代码块 以便在执行时检测错误
catch 允许定义一个要执行的代码块 如果 try 代码块中发生错误
js 语句 try 和 catch 成对出现
try {
  提供测试的代码块
}
catch (err)
{处理错误的代码块}

js 抛出错误
当发生错误 js 通常会停止并产生错误消息
js 将抛出异常(抛出错误)
js 实际上会创建带有两个属性的 error 对象 : name 和 message

throw 语句
throw 语句 允许您创建自定义错误
throw "TOO big"  //抛出文本
throw 500 //抛出数字
如果 throw 与 try 和 catch 一同使用,就可以控制程序流并生成自定义错误消息

finally 语句 允许在try 和 catch 语句块中执行代码 无论结果
try {// 提供测试的代码块}
catch (err) {// 处理错误的代码块}
finally {// 无论结果如何都执行的代码块}

error 对象
js 当错误发生时提供错误信息的内置 error 对象
error 对象 提供两个有用的属性: name 和 message

error 对象属性 name和message
name 设置或返回错误名
message 设置或返回错误消息

eval 错误
evalError 指示 eval() 函数中的错误

js 作用域
作用域指的是有权访问的变量集合
js 函数作用域
局部作用域 /全局作用域
js 拥有函数作用域: 每个函数创建一个新的作用域
作用域决定了这些变量的可访问性 可见性
函数内部定义的变量从函数外部是不可访问的 不可见的

局部 js 变量 在js函数中声明的变量,会成为函数的局部变量
局部变量的作用域是局部的 只能在函数内部访问它们
由于只能在函数内识别局部变量,因此能够在不同函数中使用 同名变量
在函数开始时会创建局部变量,在函数结束的时候会销毁

全局 js 变量
函数之外声明的变量 会成为全局变量
全局变量的作用域是全局的 网页的所有脚本和函数都能够访问它

var carName = "Volvo";
// 此处的代码能够使用 carName 变量
function myFunction() {// 此处的代码也能够使用 carName 变量}

js 变量
在 js 中 ,对象和函数也是变量 作用域决定了从代码不同部分对变量 对象和函数的可访问性

自动变量 为尚未声明的变量赋值 此变量会自动成为全局变量
通过js 全局作用域形成完整的js环境

您的全局变量(或函数) 能够覆盖 window 变量 (或函数)
任何函数,包括 window对象 能够覆盖您的全局变量和函数


js 变量的有效期
js 变量的有效期始于其被创建时.
局部变量会在函数完成时被删除
全局变量会在您关闭页面时被删除

函数参数
函数参数也是函数内的局部变量

提升 是js将声明移至顶部的默认行为
js 声明会被提升
在 js中 ,可以在使用变量之后对其进行声明
hoisting 是 js 将所有声明提升到当前作用域顶部的默认行为 提升到当前脚本或当前函数的顶部

let 和 const 关键字
用 let 或 const 声明的变量 和 常量 不会被提升
为了避免bug 需要在每个作用域的开头声明所有变量


js 严格模式
use strict 定义js代码应该以严格模式 执行
声明严格模式 通过在脚本或函数的开头添加 use strict 关键字来声明严格模式
"use strict";
myFunction();

function myFunction() {
     y = 3.14;   // 这会引发错误，因为 y 尚未声明
}

为什么使用严格模式？
严格模式使我们更容易编写“安全的” JavaScript。

严格模式把之前可接受的“坏语法”转变为真实的错误。

举例来说，在普通的 JavaScript 中，错打变量名会创建新的全局变量。在严格模式中，此举将抛出错误，这样就不可能意外创建全局变量。

在普通 JavaScript 中，如果向不可写属性赋值，开发者不会得到任何错误反馈。

在严格模式中，向不可写的、只能读取的、不存在的属性赋值，或者向不存在的变量或对象赋值，将抛出错误。



-->
<body>
<p>严格模式</p>
<p id="demo16"></p>

<p>初始化变量值</p>
<p id="demo15"></p>

<p>查找元素</p>
<p id="demo13"></p>
<p id="demo14"></p>

<p>如果向未声明的变量赋值,会自动成为全局变量:</p>
<p id="demo12"></p>

<p>myFunction() 之外的 carName 未定义.</p>
<p id="demo10"></p>
<p id="demo11"></p>

<p>请输入 5 到 10之间的数字:</p>
<input id="demo9" type="text">
<button type="button" onclick="myFunction()">检测输入</button>
<p id="p02"></p>

<p>抛出异常:</p>
<p id="demo8"></p>

<p>乘法优于加法</p>
<p id="demo7"></p>

<p>检索下面段落中的一个"e":</p>
<p id="p01">The best things in life are free!</p>
<p id="demo5"></p>
<p id="demo6"></p>

<p>在字符串中搜索 "w3school",并显示匹配的位置:</p>
<p id="demo3"></p>
<p id="demo4"></p>

<p>constructor 属性返回变量或对象的构造器函数.</p>
<p id="demo"></p>

<P>这个"自制的"isArray() 函数在数组上使用时返回 true:</P>
<p id="demo1"></p>

<p>String() 方法把数字转换为字符串.</p>
<p id="demo2"></p>

<script>
  // 严格模式
  // try {
  //   "use strict";
  //   x = 3.14;
  // }
  // catch (err) {
  //   document.getElementById("demo16").innerHTML = err.name;
  // }

  // 初始化声明变量 非初始化
  var x1 = 5,y2 = 7;
  document.getElementById("demo15").innerHTML = x1 + y2;


  // 先赋值后声明变量
  // 把 5赋值给x
  x = 5;
  // 查找元素
  elem = document.getElementById("demo13");
  // 在这个元素中显示 x
  elem.innerHTML = x;
  // declare x 声明x
  var x;

  // 先声明变量后赋值
  var y;
  y = 5;
  document.getElementById("demo14").innerHTML = y;

  myFunction2();
  // 此处的代码可以把 carName 作为全局变量使用
  document.getElementById("demo12").innerHTML = "我可以显示" + carName;
  function myFunction2() {
    carName = "porsche";
  }

  myFunction1();
  function myFunction1() {
    var carName = "porsche";
    document.getElementById("demo10").innerHTML = typeof carName + "" + carName;
  }
  document.getElementById("demo11").innerHTML = typeof carName;

  function myFunction() {
    var message,x;
    message = document.getElementById("p02");
    message.innerHTML = "";
    x = document.getElementById("demo9").value;
    try {
      if (x == "") throw "是空的";
      if (isNaN(x)) throw "不是数字";
      x = Number(x);
      if (x < 5 || x > 10) throw "不在范围内";
    }
    catch (err) {
      message.innerHTML = "输入错误: " + err;
    }
    finally {
      document.getElementById("demo9").value = "";
    }
  }

  try {
    addletrt("欢迎您,亲爱的用户!");
  }
  catch (err){
    document.getElementById("demo8").innerHTML = err.name + ": " + err.message;
  }
  document.getElementById("demo7").innerHTML = 100 + 50 * 5;

  var obj = /e/.exec("The best things in life are free!");
  document.getElementById("demo6").innerHTML = "Found" + obj[0] + "in position" + obj.index + "in the text:" + obj.input;

  text11 = document.getElementById("p01").innerHTML;
  document.getElementById("demo5").innerHTML = /e/.test(text11);

  var str = "Visit W3School!";
  var n = str.search("W3School");
  document.getElementById("demo3").innerHTML = n;

  // 正则表达式执行搜索字符串 w3school 的大小写不敏感的搜索
  var n1 = str.search(/w3school/i);
  document.getElementById("demo4").innerHTML = n1;

  // 使用字符串方法 replace() 处理字符串
  var res = str.replace("W3School", "Microsoft");

  // 使用大小写不明 的正则表达式 以"Microsoft" 替换 "W3School"


  var x = 123;
  document.getElementById("demo2").innerHTML =
    String(x) + "<br>" +
    String(123) + "<br>" +
    String(100 + 50);

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  document.getElementById("demo1").innerHTML = isArray(fruits);

  function isArray(myArray) {
    // 检查 constructor 属性来确定 某个对象是否为数组 (包含单词"Array")
    // return myArray.constructor.toString().indexOf("Array") > -1;

    // 检查对象是否是数组函数
    return myArray.constructor === Array;

    // 通过检查 constructor 属性来确定某个对象是否为日期 (包含单词"Date")
    // return myArray.constructor.toString().indexOf("Date") > -1;

    // 检查对象是否是日期函数
    // return myArray.constructor === Date;
  }

  document.getElementById("demo").innerHTML =
    "john".constructor + "<br>" +
    (3.14).constructor + "<br>" +
    false.constructor + "<br>" +
    [1, 2, 3, 4].constructor + "<br>" +
    {name: 'Bill', age: 62}.constructor + "<br>" +
    new Date().constructor + "<br>" +
    function () {
    }.constructor;
</script>

</body>
</html>
